var parse = require('co-busboy');
var path = require('path');
var fs = require('fs');

var util = require('../lib/utilx');
const {Check} = require("../lib/check");
const pkg = require("../../package.json")
const hostname = pkg.hostname
const port = pkg.staticPort

module.exports = (router) => {

    router.post('/postFile', function *() {
        var ctx = this;
        if (!this.request.is('multipart/*')) return yield next;

        var chunksNum = 0       // chunk的个数
        var currentChunk = 0    // 当前操作的chunk下标
        var chunked = false
        var guid

        var part, filename = '';
        var prefix = util.getUniqueStr(6) + '_';

        var now = new Date()
        var file_directory
        file_directory = path.join(__dirname, '../public/upload/file',(now.getUTCFullYear()).toString());
        try{
            fs.mkdirSync(file_directory)
        }catch(err){
            if(err.code !== "EEXIST")
                console.trace(err)
        }

        file_directory = path.join(file_directory,(now.getUTCMonth() + 1).toString())
        try{
            fs.mkdirSync(file_directory)
        }catch(err){
            if(err.code !== "EEXIST")
                console.trace(err)
        }

        var parts = parse(this, {
            checkFile: function (fieldname, file, _filename) {
                filename = _filename;
            }
        });
        while (part = yield parts) {
            if (part.length) {
                if (part[0] === 'name') {
                    // filename = part[1];
                } else if (part[0] == "chunk") {
                    currentChunk = parseInt(part[1])
                } else if (part[0] == "chunks") {
                    chunksNum = parseInt(part[1])
                } else if (part[0] == "guid") {
                    guid = part[1]
                }
            } else {

                if (chunksNum === 0 || !guid) {        // 不是分片上传
                    chunked = false

                    filename = prefix + filename
                    part.pipe(fs.createWriteStream(path.join(file_directory, filename)))

                } else {

                    chunked = true

                    var tmpDirPath = path.join(__dirname, `../public/upload/${guid}`)

                    if (!fs.existsSync(tmpDirPath)) {
                        fs.mkdirSync(tmpDirPath)       // 创建临时文件夹
                    }

                    filename = "0".repeat(4 - currentChunk.toString().length) + currentChunk.toString() + filename
                    part.pipe(fs.createWriteStream(path.join(tmpDirPath, filename)))

                }

            }
        }

        ctx.body = {
            guid,
            chunked,
            url: `upload/file/${(now.getUTCFullYear()).toString()}/${(now.getUTCMonth()+1).toString()}/` + filename,
            filename: filename
        };
    });

    function writeDataToFile(files,idx,tmpDirPath,ws){
        if(idx == files.length){
            return
        }

        var rs = fs.createReadStream(path.join(tmpDirPath, files[idx]))

        rs.pipe(ws,{
            end : false
        })

        rs.on("end",() => {
            writeDataToFile(files,idx + 1,tmpDirPath,ws)
            fs.unlinkSync(path.join(tmpDirPath, files[idx]))

            if(idx == files.length - 1){
                console.log("all is over")
                ws.end()
            }
        })
    }

    router.post("/merge", function *() {
        var ctx = this
        Check(ctx, "guid", "filename")

        var body = ctx.request.body

        var prefix = util.getUniqueStr(6) + '_'
        var filename = prefix + body.filename
        var tmpDirPath = path.join(__dirname, `../public/upload/${body.guid}`)

        var now = new Date();
        var file_directory
        file_directory = path.join(__dirname, '../public/upload/file',(now.getUTCFullYear()).toString());
        try{
            fs.mkdirSync(file_directory)
        }catch(err){
            if(err.code !== "EEXIST")
                console.trace(err)
        }

        file_directory = path.join(file_directory,(now.getUTCMonth() + 1).toString())
        try{
            fs.mkdirSync(file_directory)
        }catch(err){
            if(err.code !== "EEXIST")
                console.trace(err)
        }


        try {

            var files = fs.readdirSync(tmpDirPath)
            var ws = fs.createWriteStream(path.join(file_directory, filename))

            writeDataToFile(files,0,tmpDirPath,ws)

            ws.on("finish",() => {       // no more
                console.log("finish")
                fs.rmdirSync(tmpDirPath)
            })

            ctx.body = {
                url: `/upload/file/${(now.getUTCFullYear()).toString()}/${(now.getUTCMonth()+1).toString()}/` + filename
            }

        } catch (err) {        // merge出错清空
            console.error(err)

            fs
                .readdirSync(tmpDirPath)
                .forEach((e) => {
                    fs.unlinkSync(path.join(tmpDirPath, e))
                })

            fs.rmdir(tmpDirPath,() => {
                if(err){
                    console.error(err)
                }
            })

            ctx.body = {
                error: true
            }
        }
    })

    /**
     * 查询文件合并状态
     */
    router.post("/mergeStatus", function *(){
        var ctx = this
        Check(ctx,"guid")

        var body = ctx.request.body
        var tmpDirPath = path.join(__dirname, `../public/upload/${body.guid}`)

        if(! fs.existsSync(tmpDirPath)){        // 一直到删除文件夹才算完毕
            ctx.body = {
                progress : 100
            }
            return
        }

        // 存在
        var files = fs.readdirSync(tmpDirPath)
        if(files.length == 0){
            ctx.body = {
                progress : 99
            }
            return
        }
        var chunksNum = parseInt(files[files.length - 1].slice(0,4))

        ctx.body = {
            progress : 100 - files.length / (chunksNum + 1) * 100
        }
    })

    /**
     * 检查chunk是否已经被上传，保存session可以用于断点续传
     */
    router.post("/checkChunk", function *() {
        var ctx = this
        Check(ctx, "chunk", "guid", "filename")

        var body = ctx.request.body
        var filename = "0".repeat(4 - body.chunk.toString().length) + body.chunk.toString() + body.filename
        // console.log(path.join(__dirname, `../public/upload/${body.guid}`, filename))

        ctx.body = {
            is_exist: fs.existsSync(path.join(__dirname, `../public/upload/${body.guid}`, filename))
        }
    })

    /**
     * 课程被删除时或视频被覆盖时清理视频文件
     */
    router.post("/cleanVideo", function *() {
        var ctx = this
        Check(ctx, "videoLocation")

        var body = ctx.request.body

        var isDeleted = false
        var regx = /\/upload\/file\/(\w|\-|\.)*/gi

        try {

            var filename = regx.exec(body.videoLocation)[0].replace("/upload/file/", "")
            // console.log(filename)

            var file = path.join(__dirname, "../public/upload/file/", filename)
            if (fs.existsSync(file)) {
                filename !== "default.mp4" && fs.unlinkSync(file)
            }

            isDeleted = true

        } catch (err) {
            console.log(err)
            isDeleted = false
        }

        ctx.body = {
            isDeleted
        }
    })
};